﻿using System;
using System.Net;
using System.Xml;

namespace Catchbase.Service.API
{
    public class ServiceClient<T> where T : class
    {
        private readonly RequestBuilder _requestBuilder;
        private readonly JsonHelper _jsonHelper;
        private readonly CatchbaseUriBuilder _uriBuilder;
        private readonly ExceptionHandler _exceptionHandler;

        public ServiceClient(RequestBuilder requestBuilder, JsonHelper jsonHelper, CatchbaseUriBuilder uriBuilder, ExceptionHandler exceptionHandler)
        {
            _exceptionHandler = exceptionHandler;
            _uriBuilder = uriBuilder;
            _jsonHelper = jsonHelper;
            _requestBuilder = requestBuilder;
        }

        public T Get()
        {
            var uri = _uriBuilder.Build<T>();
            var request = _requestBuilder.Build(HttpMethod.GET, uri);
            var response = FetchResponse(request);
            return _jsonHelper.Read<T>(response);
        }

        public T Get(ISecurityManager securityManager)
        {
            var uri = _uriBuilder.Build<T>();
            var request = _requestBuilder.Build(HttpMethod.GET, uri);
            securityManager.SecureRequest(request);
            var response = FetchResponse(request);
            return _jsonHelper.Read<T>(response);
        }

        public T Get(string id)
        {
            var uri = _uriBuilder.Build<T>(id);
            var request = _requestBuilder.Build(HttpMethod.GET, uri);
            var response = FetchResponse(request);
            return _jsonHelper.Read<T>(response);
        }

        public void Post(T item)
        {
            var uri = _uriBuilder.Build<T>();
            var request = _requestBuilder.Build(HttpMethod.POST, uri);
            _jsonHelper.Write(request, item);
            FetchResponse(request);
        }

        public void Post(T item, ISecurityManager securityManager)
        {
            var uri = _uriBuilder.Build<T>();
            var request = _requestBuilder.Build(HttpMethod.POST, uri);
            securityManager.SecureRequest(request);
            _jsonHelper.Write(request, item);
            FetchResponse(request);
        }

        private HttpWebResponseGateway FetchResponse(HttpWebRequestGateway request)
        {
            try
            {
                return request.GetResponse();
            }
            catch (WebException ex)
            {
                _exceptionHandler.Handle(ex); throw;
            }
            catch (Exception ex)
            {
                _exceptionHandler.Handle(ex); throw;
            }
        }
    }
}